#include <iostream>

#ifdef _MSC_VER
#define PARTIAL_BUG
#endif


template <typename R,   // return
          typename I>   // input
class Outer
{
  public:

};


template <typename R,   // return
          typename I>   // input
class Base
{
  public:

    Base(Outer<R,I> *outer)
    {}

    virtual R invoke( const I &input ) = 0;
};



template <typename R,   // return
          typename I>   // input
class Derived : public Base<R, I>
{
  public:

    Derived(Outer<R,I> *outer)
      : Base<R, I>(outer)
    {}


    R invoke( const I &input )
    {
      std::cout << "Derived<R,I>\n";
      return R();
    }
};


#ifndef PARTIAL_BUG

template <typename I>   // input
class Derived<void, I> : public Base<void, I>
{
  public:

    Derived(Outer<void,I> *outer)
     : Base<void, I>(outer)
    {}

    void invoke( const I &input )
    {
      std::cout << "Derived<void,I>\n";
      // void return
    }
};

#else

void Derived<void, int>::invoke(const int &)
{
  std::cout << "special Derived<void,I>\n";
  return;
}

#endif


int main()
{
  Derived<int, int> dii(0);
  int i = dii.invoke(1);

  Derived<void, int> dvi(0);
  dvi.invoke(1);

  return 0;
}
